package 简单.模拟;

/**
 * 给你一个日期，请你设计一个算法来判断它是对应一周中的哪一天。
 * <p>
 * 输入为三个整数：day、month 和 year，分别表示日、月、年。
 * <p>
 * 您返回的结果必须是这几个值中的一个 {"Sunday", "Monday", "Tuesday",
 * "Wednesday", "Thursday", "Friday", "Saturday"}。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/day-of-the-week
 */
public class 一周中的第几天_1185 {

    public static void main(String[] args) {

        System.out.println(dayOfTheWeek(1, 1, 1972));
        System.out.println(efficientDayOfTheWeek(1, 1, 1972));

    }

    /**
     * 闰年会多出一天：
     * 年份是400的倍数，或者是4的倍数并且不是100的倍数
     * 范围在1971 年 1 月 1 日，到 2100 年 12 月 31 日之间
     * 查日历得知1971年1月1日是星期五，
     *
     * @param day
     * @param month
     * @param year
     * @return
     */
    public static String dayOfTheWeek(int day, int month, int year) {
        int days = 0;
        for (int i = 1971; i < year; i++) {  //年
            days += 365;
            if (i % 400 == 0 || (i % 4 == 0 && i % 100 != 0)) {
                days += 1;  //闰年多加一天
            }
        }
        int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};  //月
        for (int i = 0; i < month - 1; i++) {  //不包含当月
            days += months[i];
            if (i == 1 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) {  //闰年二月多一天
                days++;
            }
        }
        days += day - 1;
        String[] week = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
        return week[(days + 5) % 7];  //0对应星期天，而开始日期是星期五，要+5
    }

    /**
     * 闰年规律：四年一闰、百年不闰、四百年再闰
     * 1971-2100中的百年只有2000，而2000可以被400整除，没有打破4年一润的规律
     * 而1972是闰年，之后每四年多一天
     *
     * @param day
     * @param month
     * @param year
     * @return
     */
    public static String efficientDayOfTheWeek(int day, int month, int year) {
        int days;
        //year-1是因为不包括year年，year年是通过月份和天算的
        days = (year - 1971) * 365 + (year - 1 - 1971 + 3) / 4;  //当year=1971时，下一年就是闰年，当前是四年中的第三年
        int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};  //月
        for (int i = 0; i < month - 1; i++) {  //不包含当月
            days += months[i];
            if (i == 1 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) {  //闰年二月多一天
                days++;
            }
        }
        days += day - 1;
        String[] week = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
        return week[(days + 5) % 7];  //0对应星期天，而开始日期是星期五，要+5
    }

}
